#ifndef LOGO_VM
#define LOGO_VM
#include "Basic/String.h"
#include "Stream/FileStream.h"
#include "expression.h"
#ifdef _MSC_VER
#else
#include <cairo/cairo.h>
#endif

namespace logo
{
	using namespace zl::stream;
	class ShapeBrush
	{
	public:
#ifdef _MSC_VER
#else
		cairo_surface_t*                             surface;
		cairo_t *                                    cr;
#endif
		double                                       startx;
		double                                       starty;
		double                                       angle;
	public:
		ShapeBrush();
		~ShapeBrush();
		void                                         MV(double len);
		void                                         FD(double len);
		void                                         LT(double _angle);
		void                                         RT(double _angle);
	};

	class  lvmplugins
	{
	public:
		std::function<void(List<double>&, bool&, Ptr<ShapeBrush>&)>     function;
		std::wstring                                                    name;
		zint                                                            argc;
		lvmplugins();
		~lvmplugins();
		lvmplugins& operator=(const lvmplugins& rhs);
	};

	class  lvm
	{
	public:
		List<Ptr<Expression>>                      expressions;
		Dictionary<std::wstring, AssignmentExpression>   globalenv;
		Ptr<CodeFile>                              codes;
		List<LexError>                             lexerrs;
		List<ExpressionError>                      expressionerrs;
		Dictionary<std::wstring, lvmplugins>       cmd;
		Dictionary<std::wstring, Ptr<Expression>>  funcs;
		bool                                       stop;
		Ptr<ShapeBrush>                            brush;
	private:
		void                                       RunExp(Ptr<Expression> exp, Dictionary<std::wstring, 
			                                              AssignmentExpression>& env, bool& flag);
		void                                       Register();
	public:
		lvm();
		~lvm();
		bool                                       Init(const std::wstring& name);
		void                                       Run();
	};
};

#endif